Skip to content

Stabilize Symphony Elixir orchestration and policy handling#43

Merged
frantic-openai merged 8 commits intomainfrom
codex/model-b-writable-roots
Mar 10, 2026
Merged

Stabilize Symphony Elixir orchestration and policy handling#43
frantic-openai merged 8 commits intomainfrom
codex/model-b-writable-roots

Conversation

@frantic-openai
Copy link
Collaborator

Context

Symphony Elixir had a few correctness gaps around retry scheduling, refresh coalescing,
workspace path handling, Codex turn policy forwarding, and running-issue refreshes.

TL;DR

Stabilize Symphony Elixir orchestration, workspace safety, and Codex policy passthrough.

Summary

  • Ignore stale retry timers and coalesce superseded poll ticks in the orchestrator.
  • Canonicalize workspace paths and clarify last-known-good workflow reload behavior.
  • Pass explicit Codex turn sandbox policies through unchanged and add integration coverage.
  • Paginate Linear by-id issue-state refreshes so running issue reconciliation sees all IDs.

Alternatives

  • Keep local validation and rewriting of explicit turn sandbox policies, but that drifted from
    Codex semantics and broke documented policy types.
  • Keep single-request by-id issue refreshes, but that truncates after 50 issues and can stop
    healthy workers during reconciliation.

Test Plan

  • make -C elixir all
  • Targeted regression coverage for AppServer turn policy passthrough and Linear by-id pagination

frantic-openai and others added 8 commits March 10, 2026 11:29
Summary:
- Tokenized scheduled retry messages so retries are applied only when
  the delivered timeout matches the current retry entry.
- Ignore legacy or stale retry timeout deliveries instead of letting
  them consume newer retry metadata.
- Added a regression test covering stale retry messages.

Rationale:
- Retry cancellation alone does not prevent already-delivered timeout
  messages from racing with newer retry state.
- Matching on a per-retry token keeps retry backoff sequencing
  deterministic under mailbox races.

Tests:
- mix test test/symphony_elixir/core_test.exs
  test/symphony_elixir/orchestrator_status_test.exs

Co-authored-by: Codex <codex@openai.com>
Summary:
- Tracked the active poll timer and delivery token in orchestrator
  state.
- Replaced fire-and-forget poll scheduling with cancellable,
  tokenized tick scheduling for startup, periodic polls, and manual
  refreshes.
- Added a regression test covering repeated refresh requests and
  ignored stale tick deliveries.

Rationale:
- Manual refreshes should replace a pending poll instead of racing it
  and enqueueing duplicate poll cycles.
- Tokenized tick messages keep the scheduler deterministic even when a
  cancelled timer still delivers later.

Tests:
- mix test test/symphony_elixir/core_test.exs
  test/symphony_elixir/orchestrator_status_test.exs

Co-authored-by: Codex <codex@openai.com>
Summary:
- Added canonical path resolution for workspace and Codex cwd checks
  so symlinked roots and child paths resolve to their real locations.
- Hardened runtime turn sandbox policy resolution to reject unsafe
  types, external writable roots, relative writable roots, and
  network-enabled policies.
- Added regression coverage for symlinked workspace roots, symlink
  cwd escapes, and unsafe custom sandbox policies.

Rationale:
- Lexical prefix checks are not sufficient on macOS and other systems
  where workspace paths can traverse symlinks.
- Codex turn policies must stay bounded to the active issue workspace
  instead of accepting broader writable roots at runtime.

Tests:
- mix test test/symphony_elixir/workspace_and_config_test.exs
  test/symphony_elixir/app_server_test.exs

Co-authored-by: Codex <codex@openai.com>
Summary:
- Reconciled running workers against the IDs actually returned by the
  tracker refresh and stop workers whose issues disappear.
- Logged the missing-issue shutdown path and released claims without
  deleting the workspace.
- Added regression coverage for the missing-issue case and updated
  app-server startup expectations for canonical workspace paths.

Rationale:
- A running worker should not continue until stall timeout when the
  tracker no longer returns its issue.
- The runtime now canonicalizes workspace paths, so startup payload
  assertions must match the real bounded workspace and sandbox roots.

Tests:
- mix test test/symphony_elixir/core_test.exs
  test/symphony_elixir/orchestrator_status_test.exs

Co-authored-by: Codex <codex@openai.com>
Summary:
- Updated the Elixir README to distinguish startup failures from
  runtime workflow reload failures.
- Documented that reload errors keep the last known good workflow in
  service until the file is fixed.
- Included the formatter-only cleanup required by the final validation
  pass.

Rationale:
- The runtime intentionally keeps operating on the last known good
  workflow after a bad reload.
- The docs should match the implemented and tested behavior rather
  than describing a full scheduling halt on reload errors.

Tests:
- mix test
- mix format --check-formatted
- mix specs.check

Co-authored-by: Codex <codex@openai.com>
Summary:
- refactor writable root validation into smaller helpers that satisfy
  Credo without changing runtime behavior
- remove the unreachable empty-path branch from PathSafety
- add runtime sandbox and path safety tests to cover the remaining
  validation and error branches

Rationale:
- make all enforces formatting, lint, and 100 percent coverage
- the sandbox hardening changes introduced new branches that were not
  exercised by the existing suite

Tests:
- make all

Co-authored-by: Codex <codex@openai.com>
Summary:
- allow custom workspaceWrite writableRoots outside the issue workspace
  while still requiring absolute canonicalized paths
- keep runtime rejection for relative writable roots and
  networkAccess-enabled policies
- update tests and docs to reflect the Model B contract for trusted
  operator policy

Rationale:
- Symphony is operating in a trusted local automation model rather
  than a strict isolation harness
- the old boundary check added complexity and rejected legitimate
  shared caches or other explicit host paths

Tests:
- make all

Co-authored-by: Codex <codex@openai.com>
Summary:
- pass explicit codex turn sandbox policies through unchanged and keep
  local policy synthesis only for the default workspaceWrite case
- add integration coverage asserting AppServer forwards explicit
  sandbox policies without local rewriting
- paginate Linear issue-state refreshes by id in 50-item batches and
  preserve requested issue ordering across merged results

Rationale:
- Symphony should not impose local semantics on explicit Codex sandbox
  policy maps beyond generating its own default when omitted
- issue-state reconciliation depends on seeing the full running-id set,
  so single-page by-id fetches could wrongly stop healthy workers

Tests:
- make all

Co-authored-by: Codex <codex@openai.com>
@frantic-openai frantic-openai merged commit c9ec3f1 into main Mar 10, 2026
2 checks passed
@frantic-openai frantic-openai deleted the codex/model-b-writable-roots branch March 10, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant